#include "snakewidget.h"
#include "ui_snakewidget.h"
#include "Qpainter"
#include "QEvent"
#include "QDesktopWidget"
#include "QScreen"
#include "QApplication"
#include "QTimer"
#include "QDateTime"
#include "QMessageBox"
#include "QRect"
#include "QFont"

#define Y 20
#define X 30
#define RecHeight 25
#define RecWidth  25

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

SnakeWidget::SnakeWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SnakeWidget),
    m_timer(new QTimer(this)),
    m_foodCount(0),
    m_direction(1),
    m_startSpeed(500),
    m_score(0),
    m_level(5)
{
    ui->setupUi(this);
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    init();
}

SnakeWidget::~SnakeWidget()
{
    delete ui;
}

void SnakeWidget::init(void)
{
    setWindowTitle("贪吃蛇");
    setWindowIcon(QIcon(":/images/images/Snake_pic.ico"));
    initBackground();
    DrawSnakeHead();
    Creatfood();
    initConnect();
}

void SnakeWidget::paintEvent(QPaintEvent *)// 画贪吃蛇格子
{
    QPainter painter(this);

    for(int x = 0; x < X; x++)
    {
        for(int y = 0; y < Y; y++)
        {
            painter.drawRect(QRect(x*RecWidth, y*RecHeight, RecWidth, RecHeight));
        }
    }

    //画食物
    painter.fillRect(QRect(foodPosition[0]*RecWidth, foodPosition[1]*RecHeight, RecHeight, RecHeight), Qt::green);

    if(Snake[0][0] >= 0     &&
       Snake[0][0] <= (X-1) &&
       Snake[0][1] >= 0     &&
       Snake[0][1] <= (Y-1))// 贪吃蛇没越界
        {
            //画蛇头
            painter.fillRect(QRect(Snake[0][0]*RecWidth, Snake[0][1]*RecHeight, RecHeight, RecHeight), Qt::red);

            //画蛇身
             for(int snakeBoy = 1; snakeBoy <= m_foodCount; ++snakeBoy)
             {
                painter.fillRect(QRect(Snake[snakeBoy][0]*RecWidth, Snake[snakeBoy][1]*RecHeight, RecHeight, RecHeight), Qt::black);
             }
        }

}

void SnakeWidget::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_W)
    {
        m_direction = UP;
    }

    if(event->key() == Qt::Key_S)
    {
        m_direction = DOWN;
    }

    if(event->key() == Qt::Key_A)
    {
        m_direction = LEFT;
    }

    if(event->key() == Qt::Key_D)
    {
        m_direction = RIGHT;
    }
}

void SnakeWidget::initBackground()// 初始化背景颜色或图片
{
    setAutoFillBackground(true);
    QPalette Snakepalette;
    Snakepalette.setColor(QPalette::Background, QColor(127,255,212));
    setPalette(Snakepalette);
    this->setFixedSize(1100, 500);
    initButton();
    initGrades();
}

void SnakeWidget::DrawSnakeHead()// 随机生成蛇头及运动方向
{
    Snake[0][0] = qrand()%X;
    Snake[0][1] = qrand()%Y;

    m_direction = qrand()%4;
}

void SnakeWidget::Creatfood()// 创造一个随机食物位置
{
    foodPosition[0] = qrand()%X;
    foodPosition[1] = qrand()%Y;

    for(int i = 0; i < m_foodCount; i++)
    {
        if((foodPosition[0] == Snake[i][0])&&(foodPosition[1] == Snake[i][1]))
        {
            foodPosition[0] = qrand()%X;
            foodPosition[1] = qrand()%Y;

            i = 0;
        }
    }
}

void SnakeWidget::CheckEatfood()// 检测是否吃到食物，吃到则添加蛇身，否则将蛇身前移（蛇身跟着蛇头）
{
    if((Snake[0][0] == foodPosition[0])&&(Snake[0][1] == foodPosition[1]))
    {
        ++m_foodCount;
        m_score += 5;
        Creatfood();
    }

    for(int i = m_foodCount; i > 0; --i)
    {
        Snake[i][0] = Snake[i - 1][0];
        Snake[i][1] = Snake[i - 1][1];
    }
}

void SnakeWidget::SnakeHeadRun()// 更新蛇头位置
{
    switch (m_direction)
    {
        case UP:
            Snake[0][1]--;
            break;

        case DOWN:
            Snake[0][1]++;
            break;

        case LEFT:
            Snake[0][0]--;
            break;

        case RIGHT:
            Snake[0][0]++;
            break;

        default:
            break;
    }
}

bool SnakeWidget::SnakeOver()// 贪吃蛇达到结束条件
{
    if(Snake[0][0] < 0     ||
       Snake[0][0] > (X-1) ||
       Snake[0][1] < 0     ||
       Snake[0][1] > (Y-1))// 贪吃蛇越界
    {
        GameOver();
        return true;
    }

    for(int i = 1; i < m_foodCount; i++)
    {
        if(Snake[0][0] == Snake[i][0] &&
           Snake[0][1] == Snake[i][1])
        {
            GameOver();
            return true;
        }
    }
    return false;
}

void SnakeWidget::initConnect()// 时间溢出信号与槽的连接
{
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
    m_timer->start(m_startSpeed);

    connect(ui->RebootButton,SIGNAL(clicked()),this,SLOT(on_RebootButton_clicked()));
}

void SnakeWidget::SnakeRun()// 贪吃蛇前进
{
    CheckEatfood();
    SnakeHeadRun();
    if(SnakeOver())
    {
        return;
    }
    flashScore();
    update();
}

void SnakeWidget::GameOver()
{
    m_timer->stop();
    QMessageBox::information(this, QString::fromUtf8("Waring"), QString::fromUtf8("Game Over"));
    //ui->levelEdit->setText(QLatin1String("1"));
    //ui->scoreEdit->setText(QLatin1String("0"));
}

void SnakeWidget::initButton()// 初始化按钮信息
{
    ui->UP_Button->setGeometry(900,50,50,30);
    ui->UP_Button->setText("W");

    ui->DOWN_Button->setGeometry(900,150,50,30);
    ui->DOWN_Button->setText("S");

    ui->LEFT_Button->setGeometry(850,100,50,30);
    ui->LEFT_Button->setText("A");

    ui->RIGHT_Button->setGeometry(950,100,50,30);// 调整按钮位置
    ui->RIGHT_Button->setText("D");

    ui->AddLevel->setGeometry(860,350,30,30);

    ui->ReduceLevel->setGeometry(910,350,30,30);

    ui->RebootButton->setGeometry(970,270,100,40);
    ui->RebootButton->setText("重新开始");

}

void SnakeWidget::initGrades()
{
    QFont font("Microsoft YaHei",14,50);
    ui->Score->setGeometry(800,250,80,40);
    ui->Score->setText("分数: ");
    ui->Score->setFont(font);

    ui->Level->setGeometry(800,300,80,40);
    ui->Level->setText("难度：");
    ui->Level->setFont(font);

    ui->ScoreEdit->setGeometry(860,250,80,30);
    ui->ScoreEdit->setFont(font);
    ui->LevelEdit->setGeometry(860,300,80,30);
    ui->LevelEdit->setFont(font);
}


void SnakeWidget::flashScore()
{
    ui->ScoreEdit->setText(QString::number(m_score));
    ui->LevelEdit->setText(QString::number(m_level));
}

void SnakeWidget::RebootSnake()
{
    memset(Snake, 0, sizeof(Snake));
    memset(foodPosition, 0, sizeof(foodPosition));
    m_foodCount = 0;
    m_direction = 1;
    m_startSpeed = 500;
    m_score = 0;
    m_level = 5;

    DrawSnakeHead();
    Creatfood();
    m_timer->start(m_startSpeed);
}

void SnakeWidget::slotTimeOut()// 贪吃蛇前进时间间隔槽
{
    SnakeRun();
}


void SnakeWidget::on_UP_Button_clicked()
{
   m_direction = UP;
}

void SnakeWidget::on_LEFT_Button_clicked()
{
   m_direction = LEFT;
}

void SnakeWidget::on_RIGHT_Button_clicked()
{
   m_direction = RIGHT;
}

void SnakeWidget::on_DOWN_Button_clicked()
{
   m_direction = DOWN;
}

void SnakeWidget::on_AddLevel_clicked()
{
    if(Snake[0][0] >= 0     &&
       Snake[0][0] <= (X-1) &&
       Snake[0][1] >= 0     &&
       Snake[0][1] <= (Y-1))// 贪吃蛇没越界
    {
        m_level--;
        m_timer->start(m_level*100);
    }

}

void SnakeWidget::on_ReduceLevel_clicked()
{
    if(Snake[0][0] >= 0     &&
       Snake[0][0] <= (X-1) &&
       Snake[0][1] >= 0     &&
       Snake[0][1] <= (Y-1))// 贪吃蛇没越界
    {
        m_level++;
        m_timer->start(m_level*100);
    }
}

void SnakeWidget::on_RebootButton_clicked()
{
  RebootSnake();
}
